/*
 * FileCopyHelperTest.java
 *
 * Created on February 11, 2006, 7:11 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package custom.util;

import java.io.File;
import java.io.IOException;

/**
 *
 * @author David Armstrong
 */
public class FileCopyHelperTest implements FileCopyHelper {

    private RenameType renameType = null;
    private boolean update = false;
    private boolean confirmOverwrite = false;

    public static enum RenameType {

        Overwrite, Skip, RenameAuto, RenameManual
    }

    /** Creates a new instance of FileCopyHelperTest */
    public FileCopyHelperTest(RenameType renameType, boolean update, boolean confirmOverwrite) {
        this.renameType = renameType;
        this.update = update;
        this.confirmOverwrite = confirmOverwrite;
    }

    private boolean handleRenameAuto(final File existingFile) {
        boolean status = true;
        try {
            createNewFileWithLastModified(existingFile);
        } catch (IOException e) {
            status = false;
            handleException(e);
        }

        return true;
    }

    private String createNewName(final String fileName) {
        boolean newNameNotFound = true;
        String newFileName = null;
        int i = 0;
        while (newNameNotFound) {
            newFileName = fileName + "new_" + i;
            File newFile = new File(newFileName);
            if (newFile.exists()) {
                i++;
            } else {
                newNameNotFound = false;
            }
        }

        return newFileName;
    }

    private void createNewFileWithLastModified(final File toFile) throws IOException {
        File newToFile = new File(createNewName(toFile.getAbsolutePath()));

        if (!toFile.renameTo(newToFile)) {
            throw new IOException("File NOT renamed from \"" +
                    toFile + "\" to \"" + newToFile + "\"");
        }
        System.out.println("File renamed from \"" + toFile + "\" to \"" + newToFile + "\"");
    }

    public boolean handleFileInUse(final File existingFile) {
        boolean status = false;

        if (renameType == RenameType.Overwrite) {
            System.out.println("Overwrite failed because \"" + existingFile + "\" is in use by another process. Attempting rename.");
            status = handleRenameAuto(existingFile);
        }
        return true;
    }

    public boolean handleExistingFile(final File existingFile, final File sourceFile) throws FileCopyCancelException {
        boolean status = true;
        /* If update is true, we are supposed to make sure that the destination file is older than the source file
        before copying it. If the files are directories, however, I do not want to perform this check. The check
        will be performed for each file in the directory. */
        if ((update == true) && (!existingFile.isDirectory() && !sourceFile.isDirectory()) &&
                (existingFile.lastModified() >= sourceFile.lastModified())) {
            System.out.println("\"" + existingFile + "\" is not older than " + sourceFile + "\". Skipping file.");
            status = false;
        } else {
            if (renameType == RenameType.Skip) {
                // Rename type is skip, which means do not copy any existing files.
                System.out.println("\"" + existingFile + "\" already exists. Skipping file.");
                status = false;
            } else if (renameType == RenameType.Overwrite) {
                status = handleOverwrite(existingFile);
            } else if (renameType == RenameType.RenameAuto) {
                status = handleRenameAuto(existingFile);
            } else {
                status = handleRenameManual(existingFile);
            }
        }
        return status;
    }

    private boolean handleOverwrite(final File existingFile) throws FileCopyCancelException {
        boolean status = false;

        if (confirmOverwrite) {
            boolean wrongAnswer = false;

            // Have the user confirm the overwrite before doing so with an option pane.
            System.out.println(existingFile + " already exists. Are you sure you want to overwrite?(yes or y, yes to all or ya, no or n, no to all or na (case insensitive))");

            do {
                String answer = System.console().readLine();
                if (answer.matches("[Yy]([Ee][Ss])?")) {
                    status = true;
                    wrongAnswer = false;
                } else if (answer.matches("[Yy]([Ee][Ss] [Tt][Oo] )?[Aa]([Ll][Ll])?")) {
                    // User said yes to all, so don't confirm subsequent overwrites.
                    confirmOverwrite = false;
                    status = true;
                    wrongAnswer = false;
                } else if (answer.matches("[Nn][Oo]?")) {
                    status = false;
                    wrongAnswer = false;
                } else if (answer.matches("[Nn]([Oo] [Tt][Oo] )?[Aa]([Ll][Ll])?")) {
                    throw new FileCopyCancelException("Subsequent copy operations aborted");
                } else {
                    wrongAnswer = true;
                    System.out.println(answer + " is an invalid answer. Valid answers are: (yes or y, yes to all or ya, no or n, no to all or na (case insensitive)) Do you want to overwrite?");
                }
            } while (wrongAnswer == true);
        } else {
            // No need to confirm overwrite, so return true.
            status = true;
        }

        return status;
    }

    private boolean handleRenameManual(final File existingFile) throws FileCopyCancelException {
        boolean status = true;
        try {
            status = promptForNewName(existingFile);
        } catch (IOException e) {
            status = false;
            handleException(e);
        }

        if (status == false) {
            // Log the fact that renaming failed to the log file.
            System.out.println("Renaming of \"" + existingFile + "\" failed. Do you want to abort subsequent copy operations(yes or y, or no n (case insensitive))");
            boolean wrongAnswer = false;

            do {
                String answer = System.console().readLine();
                if (answer.matches("[Yy]([Ee][Ss])?")) {
                    throw new FileCopyCancelException("Subsequent copy operations aborted");
                } else if (answer.matches("[Nn][Oo]?")) {
                    wrongAnswer = false;
                } else {
                    wrongAnswer = true;
                    System.out.println(answer + " is an invalid answer. Valid answers are: (yes or y, or no n (case insensitive)) Do you want to abort subsequent copy operations?");
                }
            } while (wrongAnswer == true);
        }

        return status;
    }

    private boolean promptForNewName(final File toFile) throws IOException, FileCopyCancelException {
        boolean status = false;
        File newToFile = new File(toFile.getParent(), createNewName(toFile.getName()));

        System.out.println();
        System.out.println("\"" + toFile + "\" already exists. To what do you want to rename the file? (To rename the file to \"" +
                newToFile.getName() + "\" press Enter");
        String answer = System.console().readLine();

        if (!answer.equals("")) {
            newToFile = new File(newToFile.getParent() + System.getProperty("file.separator"), answer);
        }
        if (!toFile.renameTo(newToFile)) {
            throw new IOException("File NOT renamed from \"" + toFile + "\" to \"" + newToFile + "\"");
        }
        System.out.println("File renamed from \"" + toFile + "\" to \"" + newToFile + "\"");
        status = true;

        return status;
    }

    public void handleException(final IOException e) {
        System.out.println(e.getMessage());
    }

    public int getRestoreCount() {
        return 0;
    }

    public void reportCopyStatus(final String msg, boolean status) {
        System.out.println(msg);
    }
}
